package org.jeemp.common.auth;

import cn.hutool.core.codec.Base64;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultJwtBuilder;
import io.jsonwebtoken.impl.DefaultJwtParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPrivateKey;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Optional;
import java.util.UUID;

import static java.util.Optional.empty;
import static java.util.stream.Collectors.joining;

/**
 * @author JackRen
 * @date 2021-02-02 15:57
 * @description: 生成token
 *
 */
@Service
public class JwtService {

    private Logger LOG = LoggerFactory.getLogger(getClass());

    @Value("${jwt.key.store}")
    private String keystore;

    @Value("${jwt.key.pass}")
    private String keypass;

    @Value("${jwt.key.alias}")
    private String keyalias;

    @Value("${jwt.cert}")
    private String cert;

    private PrivateKey privateKey;
    private PublicKey publicKey;


    /**
     * 初始化
     */
    @PostConstruct
    private void init() throws Exception {
        char[] pass = keypass.toCharArray();
        KeyStore from = KeyStore.getInstance("JKS", "SUN");
        from.load(new ClassPathResource(keystore).getInputStream(), pass);
        privateKey =(PrivateKey) from.getKey(keyalias, pass);
        LOG.info("私钥："+new String(Base64.encode(privateKey.getEncoded())));

        CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509");
        X509Certificate x509Cert = (X509Certificate) certificatefactory.generateCertificate(new ClassPathResource(cert).getInputStream());
        publicKey = x509Cert.getPublicKey();
        LOG.info("公钥："+new String(Base64.encode(publicKey.getEncoded())));

        String token = generate();
        LOG.info("token："+token);
    }

    /**
     * 生成token
     */
    public String generate() {
        return new DefaultJwtBuilder()
                .setId(UUID.randomUUID().toString())
                .setSubject("elvis")
                .setExpiration(Date.from(ZonedDateTime.now().plusWeeks(1).toInstant()))
                .claim("authority", "123")
                .claim("affiliation", "456")
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    }

    /**
     * 解析token
     */
    public String parse(String token) {
        try {
            if ("".equals(token) || "".equals(token.trim())){
                return "";
            }
            Jws<Claims> jws = new DefaultJwtParser()
                    .setSigningKey(publicKey)
                    .parseClaimsJws(token);
            Claims claims = jws.getBody();
            String subject = claims.getSubject();
            String affiliation = claims.get("affiliation", String.class);
            return subject+"----"+affiliation;
        } catch (Exception e) {
            LOG.error("failed to parse jwt token {}: ", token, e);
        }
        return "";
    }

}
